package com.bdqn.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * AspectLogger 切面日志处理类
 *
 * @author LILIBO
 * @since 2024/7/16
 */
@Aspect
@Component
public class AspectLogger {

    private final Logger log = Logger.getLogger(AspectLogger.class);

    /**
     * 前置增强
     *
     * @param jp
     */
    @Before("execution(* com.bdqn.service..*.*(..))")
    public void before(JoinPoint jp) {
        log.info("【前置增强】调用" + jp.getTarget() + "的" + jp.getSignature().getName() + "方法。参数：" + Arrays.toString(jp.getArgs()));
    }

    /**
     * 异常抛出增强
     *
     * @param jp
     * @param e
     */
    @AfterThrowing(pointcut = "execution(* com.bdqn.service..*.*(..))", throwing = "e")
    public void afterThrowing(JoinPoint jp, RuntimeException e) {
        log.error("【异常抛出增强】调用" + jp.getTarget() + "的" + jp.getSignature().getName() + "方法。发生异常：" + e);
    }

    /**
     * 后置增强
     *
     * @param jp
     * @param result
     */
    @AfterReturning(pointcut = "execution(* com.bdqn.service..*.*(..))", returning = "result")
    public void afterReturning(JoinPoint jp, Object result) {
        log.info("【后置增强】调用" + jp.getTarget() + "的" + jp.getSignature().getName() + "方法。返回值：" + result);
    }

    /**
     * 最终增强
     *
     * @param jp
     */
    @After("execution(* com.bdqn.service..*.*(..))")
    public void after(JoinPoint jp) {
        log.info("【最终增强】调用" + jp.getTarget() + "的" + jp.getSignature().getName() + "方法。");
    }

    /**
     * 环绕增强
     *
     * @param jp
     * @return
     */
    public Object around(ProceedingJoinPoint jp) {
        log.info("【环绕增强】");
        log.info("[前置增强] 调用" + jp.getTarget() + "的" + jp.getSignature().getName() + "方法。");
        Object result = null;
        try {
            // 调用真实方法（被代理的方法）
            result = jp.proceed();
            // result = "不调用！";
            log.info("[后置增强] 调用" + jp.getTarget() + "的" + jp.getSignature().getName() + "方法。返回值：" + result);
        } catch (Throwable e) {
            e.printStackTrace();
            log.error("[异常抛出增强] 调用" + jp.getTarget() + "的" + jp.getSignature().getName() + "方法。发生异常：" + e);
        } finally {
            log.info("[最终增强] 调用" + jp.getTarget() + "的" + jp.getSignature().getName() + "方法。");
        }
        return result;
    }

}
